﻿using System.Collections.ObjectModel;
using System.Linq;
using System.Windows.Markup;
using Common.Core.Configuration;
using Microsoft.Practices.Unity;
using Microsoft.Practices.Unity.Configuration;

namespace Common.Unity.Configuration
{
	[ContentProperty( "Types" )]
	public class UnityContainer : IObjectCreator<Microsoft.Practices.Unity.UnityContainer>
	{
		public ObservableCollection<UnityType> Types
		{
			get { return types ?? ( types = new ObservableCollection<UnityType>() ); }
		}	ObservableCollection<UnityType> types;

		public ObservableCollection<UnityContainerExtension> Extensions
		{
			get { return extensions ?? ( extensions = new ObservableCollection<UnityContainerExtension>() ); }
		}	ObservableCollection<UnityContainerExtension> extensions;

		public ObservableCollection<UnityInstance> Instances
		{
			get { return instances ?? ( instances = new ObservableCollection<UnityInstance>() ); }
		}	ObservableCollection<UnityInstance> instances;

		public ObservableCollection<IContainerConfigurationCommand> Configurations
		{
			get { return configurations ?? ( configurations = new ObservableCollection<IContainerConfigurationCommand>() ); }
		}	ObservableCollection<IContainerConfigurationCommand> configurations;
        
		public Microsoft.Practices.Unity.UnityContainer Instance
		{
			get { return instance ?? ( instance = Create() ); }
		}	Microsoft.Practices.Unity.UnityContainer instance;

		Microsoft.Practices.Unity.UnityContainer Create()
		{
			var result = new Microsoft.Practices.Unity.UnityContainer();

			// Add extensions:
			foreach ( var extension in Extensions )
			{
				result.AddExtension( extension );
			}

			// Go through commands:
			var commands = Instances.Cast<IContainerConfigurationCommand>().Concat( Types.Cast<IContainerConfigurationCommand>() ).Concat( Configurations );
			foreach ( var command in commands )
			{
				command.Configure( result );
			}

			return result;
		}
	}
}
